package com.smartcampusbackend.service.impl;

import com.smartcampusbackend.model.AcademicWarning;
import com.smartcampusbackend.model.Course;
import com.smartcampusbackend.model.Grade;
import com.smartcampusbackend.model.User;
import com.smartcampusbackend.model.MakeupExamApplication;
import com.smartcampusbackend.mapper.AcademicWarningMapper;
import com.smartcampusbackend.mapper.CourseMapper;
import com.smartcampusbackend.mapper.GradeMapper;
import com.smartcampusbackend.mapper.UserMapper;
import com.smartcampusbackend.mapper.MakeupExamApplicationMapper;
import com.smartcampusbackend.service.AcademicWarningService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class AcademicWarningServiceImpl implements AcademicWarningService {
    private static final Logger logger = LoggerFactory.getLogger(AcademicWarningServiceImpl.class);
    
    @Autowired
    private AcademicWarningMapper academicWarningMapper;
    
    @Autowired
    private GradeMapper gradeMapper;
    
    @Autowired
    private CourseMapper courseMapper;
    
    @Autowired
    private UserMapper userMapper;
    
    @Autowired
    private MakeupExamApplicationMapper makeupExamApplicationMapper;

    @Override
    public List<AcademicWarning> listStudentWarnings(Long studentId) {
        logger.info("获取学生学业预警，studentId: {}", studentId);
        // 尝试转换学生ID为字符串格式，因为数据库可能存储的是字符串形式
        String studentIdStr = String.valueOf(studentId);
        
        // 首先尝试使用Long类型的studentId查询
        List<AcademicWarning> warnings = academicWarningMapper.selectList(
            new QueryWrapper<AcademicWarning>()
                .eq("student_id", studentId)
                .orderByDesc("warning_date")
        );
        
        // 如果没有结果，尝试使用字符串类型的studentId查询
        if (warnings.isEmpty()) {
            warnings = academicWarningMapper.selectList(
                new QueryWrapper<AcademicWarning>()
                    .eq("student_id", studentIdStr)
                    .orderByDesc("warning_date")
            );
            logger.info("使用字符串ID查询到学业预警数量: {}", warnings.size());
        }
        
        return warnings;
    }

    @Override
    public List<AcademicWarning> listStudentWarningsStr(String studentId) {
        logger.info("获取学生学业预警（字符串版本），studentId: {}", studentId);
        
        // 直接使用字符串ID查询
        List<AcademicWarning> warnings = academicWarningMapper.selectList(
            new QueryWrapper<AcademicWarning>()
                .eq("student_id", studentId)
                .orderByDesc("warning_date")
        );
        
        // 补充警告信息，确保教师姓名等字段有值
        for (AcademicWarning warning : warnings) {
            if (warning.getTeacherName() == null || warning.getTeacherName().isEmpty()) {
                try {
                    User teacher = userMapper.selectById(warning.getTeacherId());
                    if (teacher != null) {
                        warning.setTeacherName(teacher.getRealName());
                    }
                } catch (Exception e) {
                    logger.warn("获取教师信息失败: {}", e.getMessage());
                }
            }
            
            // 确保课程信息完整
            if (warning.getCourseName() == null || warning.getCourseName().isEmpty() || 
                warning.getSemester() == null || warning.getCourseCredit() == null) {
                try {
                    Course course = courseMapper.selectById(warning.getCourseId());
                    if (course != null) {
                        warning.setCourseName(course.getName());
                        warning.setSemester(course.getSemester());
                        warning.setCourseCredit(course.getCredits() != null ? course.getCredits().doubleValue() : null);
                    }
                } catch (Exception e) {
                    logger.warn("获取课程信息失败: {}", e.getMessage());
                }
            }
        }
        
        logger.info("查询到学业预警数量: {}", warnings.size());
        return warnings;
    }

    @Override
    public List<AcademicWarning> listAdminWarnings(Long userId) {
        logger.info("管理员查看所有学业预警");
        return academicWarningMapper.selectList(
            new QueryWrapper<AcademicWarning>()
                .orderByDesc("warning_date")
        );
    }
    
    @Override
    public List<AcademicWarning> listTeacherWarnings(Long teacherId) {
        logger.info("教师查看课程学业预警，teacherId: {}", teacherId);
        // 尝试转换教师ID为字符串格式，因为数据库可能存储的是字符串形式
        String teacherIdStr = String.valueOf(teacherId);
        
        // 首先尝试使用Long类型的teacherId查询
        List<AcademicWarning> warnings = academicWarningMapper.selectList(
            new QueryWrapper<AcademicWarning>()
                .eq("teacher_id", teacherId)
                .orderByDesc("warning_date")
        );
        
        // 如果没有结果，尝试使用字符串类型的teacherId查询
        if (warnings.isEmpty()) {
            warnings = academicWarningMapper.selectList(
                new QueryWrapper<AcademicWarning>()
                    .eq("teacher_id", teacherIdStr)
                    .orderByDesc("warning_date")
            );
            logger.info("使用字符串ID查询到教师学业预警数量: {}", warnings.size());
        }
        
        return warnings;
    }
    
    @Override
    public List<Map<String, Object>> getWarningStatsByTeacher(Long teacherId) {
        logger.info("获取教师课程学业预警统计，teacherId: {}", teacherId);
        List<Map<String, Object>> result = new ArrayList<>();
        
        // 尝试使用不同类型的teacherId查询
        String teacherIdStr = String.valueOf(teacherId);
        
        // 获取教师的所有课程，尝试不同类型的ID
        List<Course> courses = courseMapper.selectList(
            new QueryWrapper<Course>()
                .eq("teacher_id", teacherId)
        );
        
        // 如果没有找到课程，尝试使用字符串ID
        if (courses.isEmpty()) {
            courses = courseMapper.selectList(
                new QueryWrapper<Course>()
                    .eq("teacher_id", teacherIdStr)
            );
            logger.info("使用字符串ID查询到教师课程数量: {}", courses.size());
        }
        
        for (Course course : courses) {
            try {
                // 统计每个课程的学业预警数量
                int warningCount = academicWarningMapper.selectCount(
                    new QueryWrapper<AcademicWarning>()
                        .eq("course_id", course.getId())
                        .eq("status", "ACTIVE")
                ).intValue();
                
                if (warningCount > 0) {
                    Map<String, Object> courseStats = new HashMap<>();
                    courseStats.put("courseId", course.getId());
                    courseStats.put("courseName", course.getName());
                    courseStats.put("warningCount", warningCount);
                    courseStats.put("semester", course.getSemester());
                    courseStats.put("credits", course.getCredits());
                    result.add(courseStats);
                }
            } catch (Exception e) {
                logger.error("统计课程学业预警时出错: courseId={}, error={}", course.getId(), e.getMessage());
            }
        }
        
        return result;
    }
    
    @Override
    public List<Map<String, Object>> getAllWarningStats() {
        logger.info("获取所有课程学业预警统计");
        List<Map<String, Object>> result = new ArrayList<>();
        
        // 获取所有课程
        List<Course> courses = courseMapper.selectList(new QueryWrapper<>());
        
        for (Course course : courses) {
            // 统计每个课程的学业预警数量
            int warningCount = academicWarningMapper.selectCount(
                new QueryWrapper<AcademicWarning>()
                    .eq("course_id", course.getId())
                    .eq("status", "ACTIVE")
            ).intValue();
            
            if (warningCount > 0) {
                Map<String, Object> courseStats = new HashMap<>();
                courseStats.put("courseId", course.getId());
                courseStats.put("courseName", course.getName());
                courseStats.put("warningCount", warningCount);
                courseStats.put("semester", course.getSemester());
                courseStats.put("credits", course.getCredits());
                courseStats.put("teacherId", course.getTeacherId());
                
                // 获取教师姓名
                User teacher = userMapper.selectById(course.getTeacherId());
                courseStats.put("teacherName", teacher != null ? teacher.getRealName() : "未知");
                
                result.add(courseStats);
            }
        }
        
        return result;
    }
    
    @Override
    public List<Map<String, Object>> getWarningStudentsByCourse(String courseId) {
        logger.info("获取课程学业预警学生列表，courseId: {}", courseId);
        List<Map<String, Object>> result = new ArrayList<>();
        
        // 获取该课程的所有学业预警
        List<AcademicWarning> warnings = academicWarningMapper.selectList(
            new QueryWrapper<AcademicWarning>()
                .eq("course_id", courseId)
                .eq("status", "ACTIVE")
        );
        
        for (AcademicWarning warning : warnings) {
            Map<String, Object> studentWarning = new HashMap<>();
            
            // 获取学生信息
            User student = null;
            
            // 先尝试用Long类型ID查询
            if (warning.getStudentId() != null) {
                student = userMapper.selectById(warning.getStudentId());
            }
            
            // 如果没找到，尝试用字符串ID查询
            if (student == null) {
                String studentIdStr = String.valueOf(warning.getStudentId());
                // 使用QueryWrapper直接通过字符串ID查询
                student = userMapper.selectOne(new QueryWrapper<User>().eq("id", studentIdStr));
            }
            
            if (student != null) {
                // 这里确保studentId存储为字符串格式，便于前端处理
                studentWarning.put("studentId", String.valueOf(student.getId()));
                studentWarning.put("studentName", student.getRealName());
                studentWarning.put("studentNumber", student.getUsername());
                studentWarning.put("warningId", warning.getId());
                studentWarning.put("warningType", warning.getWarningType());
                studentWarning.put("warningDate", warning.getWarningDate());
                studentWarning.put("status", warning.getStatus());
                studentWarning.put("description", warning.getDescription());
                
                // 查询补考申请
                MakeupExamApplication makeup = makeupExamApplicationMapper.selectOne(
                    new QueryWrapper<MakeupExamApplication>()
                        .eq("student_id", String.valueOf(student.getId()))
                        .eq("course_id", courseId)
                );
                if (makeup != null) {
                    studentWarning.put("makeupStatus", makeup.getStatus());
                    studentWarning.put("makeupScore", makeup.getMakeupScore());
                    studentWarning.put("makeupApplicationId", makeup.getId());
                } else {
                    studentWarning.put("makeupStatus", "未申请");
                }
                
                result.add(studentWarning);
            } else {
                logger.warn("未找到学生信息，studentId: {}", warning.getStudentId());
            }
        }
        
        logger.info("找到课程 {} 的预警学生数量: {}", courseId, result.size());
        return result;
    }
    
    @Override
    @Transactional
    public void generateWarningsFromGrades() {
        logger.info("从不及格成绩生成学业预警");
        
        // 查询所有不及格的成绩（小于60分）
        List<Grade> failedGrades = gradeMapper.selectList(
            new QueryWrapper<Grade>()
                .lt("final_grade", 60.0)
        );
        
        logger.info("找到不及格成绩数量: {}", failedGrades.size());
        
        int generatedCount = 0;
        
        for (Grade grade : failedGrades) {
            try {
                String studentId = grade.getStudentId();
                String courseId = grade.getCourseId();
                
                logger.info("处理不及格成绩: studentId={}, courseId={}, score={}", studentId, courseId, grade.getFinalGrade());
                
                // 检查是否已经存在该课程的预警（同时检查Long类型和String类型的ID）
                int existingCount = academicWarningMapper.selectCount(
                    new QueryWrapper<AcademicWarning>()
                        .eq("student_id", studentId)
                        .eq("course_id", courseId)
                ).intValue();
                
                if (existingCount == 0) {
                    // 尝试使用Long类型的student_id查询
                    try {
                        Long studentIdLong = Long.valueOf(studentId);
                        existingCount = academicWarningMapper.selectCount(
                            new QueryWrapper<AcademicWarning>()
                                .eq("student_id", studentIdLong)
                                .eq("course_id", courseId)
                        ).intValue();
                    } catch (Exception e) {
                        logger.warn("无法将学生ID转换为Long: {}", studentId);
                    }
                }
                
                if (existingCount == 0) {
                    // 获取课程信息
                    Course course = courseMapper.selectById(courseId);
                    if (course == null) {
                        logger.warn("未找到课程信息，courseId: {}", courseId);
                        continue;
                    }
                    
                    // 获取教师信息
                    User teacher = userMapper.selectById(course.getTeacherId());
                    String teacherName = teacher != null ? teacher.getRealName() : "未知";
                    
                    // 获取学生信息
                    User student = userMapper.selectById(studentId);
                    String studentName = student != null ? student.getRealName() : "未知";
                    
                    logger.info("为学生 {} 创建课程 {} 的学业预警", studentName, course.getName());
                    
                    // 创建学业预警
                    AcademicWarning warning = new AcademicWarning();
                    // 尝试转换为Long类型，如果失败则使用字符串形式
                    try {
                        warning.setStudentId(Long.valueOf(studentId));
                    } catch (Exception e) {
                        // 如果转换失败，修改实体类对应字段类型为String
                        logger.warn("无法将学生ID转换为Long，使用原始值: {}", studentId);
                        // 这里不设置studentId，因为实体要求Long类型
                    }
                    warning.setCourseId(courseId);
                    warning.setCourseName(course.getName());
                    warning.setTeacherId(course.getTeacherId());
                    warning.setTeacherName(teacherName);
                    warning.setSemester(grade.getSemester());
                    warning.setCourseCredit(Double.valueOf(course.getCredits()));
                    warning.setWarningType("成绩不及格");
                    warning.setDescription(String.format(
                        "学生 %s 在课程 %s 中成绩不及格，最终成绩为 %.1f 分，低于及格线 60 分。",
                        studentName, course.getName(), grade.getFinalGrade()
                    ));
                    warning.setWarningDate(LocalDateTime.now());
                    warning.setStatus("ACTIVE");
                    warning.setCreateTime(LocalDateTime.now());
                    warning.setUpdateTime(LocalDateTime.now());
                    
                    try {
                        int result = academicWarningMapper.insert(warning);
                        if (result > 0) {
                            generatedCount++;
                            logger.info("成功创建学业预警: 学生ID={}, 课程ID={}, 课程名称={}", 
                                      studentId, courseId, course.getName());
                        }
                    } catch (Exception e) {
                        logger.error("插入学业预警记录失败: {}", e.getMessage(), e);
                    }
                } else {
                    logger.info("已存在学业预警记录，跳过: 学生ID={}, 课程ID={}", 
                              studentId, courseId);
                }
            } catch (Exception e) {
                logger.error("生成学业预警失败，studentId: {}, courseId: {}, error: {}", 
                           grade.getStudentId(), grade.getCourseId(), e.getMessage(), e);
            }
        }
        
        logger.info("成功生成 {} 条学业预警", generatedCount);
    }
    
    @Override
    public boolean updateWarningStatus(Long warningId, String status) {
        logger.info("更新学业预警状态，warningId: {}, status: {}", warningId, status);
        
        AcademicWarning warning = academicWarningMapper.selectById(warningId);
        if (warning == null) {
            logger.error("学业预警不存在，warningId: {}", warningId);
            return false;
        }
        
        warning.setStatus(status);
        warning.setUpdateTime(LocalDateTime.now());
        
        return academicWarningMapper.updateById(warning) > 0;
    }
    
    @Override
    public boolean hasUnresolvedWarnings(Long studentId) {
        logger.info("检查学生是否有未解决的学业预警，studentId: {}", studentId);
        
        int count = academicWarningMapper.selectCount(
            new QueryWrapper<AcademicWarning>()
                .eq("student_id", studentId.toString())
                .eq("status", "ACTIVE")
        ).intValue();
        
        logger.info("学生{}有{}条未解决的学业预警", studentId, count);
        return count > 0;
    }
} 